/*
 * Part of the ACID Project
 * Developed in 2011 by Morgan Taschuk
 */
package acid.plugin.expression;

import acid.plugin.gui.ConfigurationOptions;
import acid.spring.db.Experiment;
import acid.spring.db.GeneAlias;
import acid.spring.db.Organism;
import acid.spring.db.Tissue;
import cytoscape.Cytoscape;
import cytoscape.data.CyAttributes;
import cytoscape.task.Task;
import cytoscape.task.TaskMonitor;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 *
 * @author morgan
 */
public class ShowExpressionData implements Task
{

    private TaskMonitor taskMonitor;
    private double maxPVal;
    private double minFoldChange;
    private Organism organism;
    private ReadExpressionData red=null;
    private Map<String, Set<GeneAlias>> cyIdToGeneAlias;
    private List<Tissue> tissues;

    public void setExperiments(List<Experiment> experiments)
    {
        this.experiments = experiments;
    }

    public void setTissues(List<Tissue> tissues)
    {
        this.tissues = tissues;
    }
    List<Experiment> experiments;

    private void initialize()
    {
        if (red==null)
        {
            red = new ReadExpressionData(ConfigurationOptions.ALIAS_ATT, maxPVal, minFoldChange);
            cyIdToGeneAlias = red.getGeneAliases();
        }
    }

    public ShowExpressionData(double maxPVal, double minFoldChange, Organism organism)
    {
        this.maxPVal = maxPVal;
        this.minFoldChange = minFoldChange;
        this.organism = organism;
//        System.out.println(toString());
    }

    private void showAllExpressionData()
    {
        CyAttributes attrs = Cytoscape.getNodeAttributes();
        int count = 0, total = cyIdToGeneAlias.keySet().size();

        taskMonitor.setStatus("Retrieving expression data...");
        for (String s : cyIdToGeneAlias.keySet())
        {
            //System.out.println("\t" + s + " -> " + cyIdToGeneAlias.get(s));

            String url = red.getUrl(cyIdToGeneAlias.get(s), maxPVal, minFoldChange);
            //System.out.println(url);

            if (url != null)
            {
                Map map = red.getExpressionValues(cyIdToGeneAlias.get(s));
                attrs.setMapAttribute(s, "expression_vals", map);
                attrs.setAttribute(s, "url", url);
            }
            taskMonitor.setPercentCompleted(Math.min(100, count++ * 100 / total));
        }

        taskMonitor.setStatus("Redrawing network");
        Cytoscape.getCurrentNetworkView().redrawGraph(true, true);
    }

    private void showExpressionDataByTissue()
    {
        CyAttributes attrs = Cytoscape.getNodeAttributes();
        int count = 0, total = cyIdToGeneAlias.keySet().size() * tissues.size();

        for (Tissue tissue : tissues)
        {
            taskMonitor.setStatus("Retrieving expression data for " + tissue.getName() + "...");
            for (String s : cyIdToGeneAlias.keySet())
            {
                //System.out.println("\t" + s + " -> " + cyIdToGeneAlias.get(s));
                String url = red.getTissueUrl(cyIdToGeneAlias.get(s), maxPVal,
                        minFoldChange, tissue);
                //System.out.println(url);
                if (url != null)
                {
                    attrs.setAttribute(s, "url-" + tissue.getName().replace(" ", "_"), url);
                }
                taskMonitor.setPercentCompleted(Math.min(100, count++ * 100 / total));
            }
        }
        taskMonitor.setStatus("Redrawing network");
        Cytoscape.getCurrentNetworkView().redrawGraph(true, true);
    }

    private void showExpressionDataByExperiment()
    {
        CyAttributes attrs = Cytoscape.getNodeAttributes();
        int count = 0, total = cyIdToGeneAlias.keySet().size() * experiments.size();
        for (Experiment experiment : experiments)
        {
            taskMonitor.setStatus("Retrieving expression data for " + experiment.getName() + "...");
            for (String s : cyIdToGeneAlias.keySet())
            {
                //System.out.println("\t" + s + " -> " + cyIdToGeneAlias.get(s));
                String url = red.getExperimentUrl(cyIdToGeneAlias.get(s), maxPVal,
                        minFoldChange, experiment);
                //System.out.println(url);

                if (url != null)
                {
                    attrs.setAttribute(s, "url-" + experiment.getName().replace(" ", "_"), url);
                }
                taskMonitor.setPercentCompleted(Math.min(100, count++ * 100 / total));
            }
        }
        taskMonitor.setStatus("Redrawing network");
        Cytoscape.getCurrentNetworkView().redrawGraph(true, true);
    }

    @Override
    public String toString()
    {
        return "ShowExpressionData{" + "maxPVal=" + maxPVal + "minFoldChange=" + minFoldChange + "organism=" + organism +'}';
    }

    /**
     * Get the value of organism
     *
     * @return the value of organism
     */
    public Organism getOrganism()
    {
        return organism;
    }

    /**
     * Set the value of organism
     *
     * @param organism new value of organism
     */
    public void setOrganism(Organism organism)
    {
        this.organism = organism;
    }

    /**
     * Get the value of maxPVal
     *
     * @return the value of maxPVal
     */
    public double getMaxPVal()
    {
        return maxPVal;
    }

    /**
     * Set the value of maxPVal
     *
     * @param maxPVal new value of maxPVal
     */
    public void setMaxPVal(double maxPVal)
    {
        this.maxPVal = maxPVal;
    }

    /**
     * Get the value of minFoldChange
     *
     * @return the value of minFoldChange
     */
    public double getMinFoldChange()
    {
        return minFoldChange;
    }

    /**
     * Set the value of minFoldChange
     *
     * @param minFoldChange new value of minFoldChange
     */
    public void setMinFoldChange(double minFoldChange)
    {
        this.minFoldChange = minFoldChange;
    }

    public ReadExpressionData getRed()
    {
        return red;
    }

    

    @Override
    public void run()
    {
        taskMonitor.setPercentCompleted(-1);
        initialize();
        if (tissues != null)
        {
            showExpressionDataByTissue();
        }
        else if (experiments != null)
        {
            showExpressionDataByExperiment();
        }
        else
        {
            showAllExpressionData();
        }
    }

    @Override
    public void halt()
    {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void setTaskMonitor(TaskMonitor monitor) throws IllegalThreadStateException
    {
        taskMonitor = monitor;
    }

    @Override
    public String getTitle()
    {
        return "Overlay expression data";
    }
}
